package com.foreveross.proxyip.core.redis;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Set;

import redis.clients.jedis.Transaction;

import com.foreveross.proxyip.entity.ProxyIpBean;
import com.foreveross.proxyip.util.SerializeUtil;

public class PoolMap extends Map {

	
	public PoolMap(String keyName ) {
		
		super(keyName);
	}

	@Override
	public Long size() throws PiRedisExecption {
		return new RedisExecutor<Long>() {
			@Override
			public Long run() throws Exception {
				Long len = jedis.zcard(keyName);
				return len;
			}
		}.exec();
	}
	
//	public Long size(Jedis redis) {
//		
//		try{
//			if(redis==null){
//				redis = getRedis();
//			}
//			Long len = redis.zcard(keyName);
//		}catch(Exception e){
//			pool.returnBrokenResource(redis);
//			throw new RuntimeException(e);
//		}finally{
//			pool.returnResource(redis);
//		}
//		
//	}

	@Override
	public boolean isEmpty() throws PiRedisExecption {
		return new RedisExecutor<Boolean>() {
			@Override
			public Boolean run() throws Exception {
				if(jedis.zcard(keyName)==0){
					jedis.del(keyName);
					return true;
				}
				return false;
			}
		}.exec();
		
		
//		Jedis redis = null;
//		try{
//			redis = getRedis();
//			if(redis.zcard(keyName)==0){
//				redis.del(keyName);
//				return true;
//			}
//			return false;
//		}catch(Exception e){
//			pool.returnBrokenResource(redis);
//			throw new RuntimeException(e);
//		}finally{
//			pool.returnResource(redis);
//		}
	}

	@Override
	public boolean containsKey(final String key) throws PiRedisExecption {
		return new RedisExecutor<Boolean>() {
			@Override
			public Boolean run() throws Exception {
				if(key==null){
					return false;
				}
				if(jedis.zrank(keyName, key)==null){//有相应对象
					return false;
				}else{
					return true;
				}
			}
		}.exec();
		
//		return containsKey(null, key);
	}
	
//	@Override
//	public boolean containsKey(Jedis redis, String key) {
//		try{
//			
//			if(redis==null){
//				redis = getRedis();
//			}
//			if(key==null){
//				return false;
//			}
//			if(redis.zrank(keyName, key)==null){//有相应对象
//				return false;
//			}else{
//				return true;
//			}
//		}catch(Exception e){
//			pool.returnBrokenResource(redis);
//			throw new RuntimeException(e);
//		}finally{
//			pool.returnResource(redis);
//		}
//	}

/*	public AbstractStoreBean get(final String key) throws PiRedisExecption {
		return new RedisExecutor<AbstractStoreBean>() {
			@Override
			public AbstractStoreBean run() throws Exception {
				if(jedis.zrank(keyName, key)!=null){//有相应对象
					byte[] bytes = jedis.get(key.getBytes());
					if(bytes==null){
						jedis.zrem(keyName, key);
					}
					return (AbstractStoreBean)SerializeUtil.unserialize(bytes);
				}else{
					return null;
				}
			}
		}.exec();*/
		
//		Jedis redis = null;
//		try{
//			redis = getRedis();
//			if(redis.zrank(keyName, key)!=null){//有相应对象
//				byte[] bytes = redis.get(key.getBytes());
//				if(bytes==null){
//					redis.zrem(keyName, key);
//				}
//				return (AbstractStoreBean)SerializeUtil.unserialize(bytes);
//			}else{
//				return null;
//			}
//		}catch(Exception e){
//			pool.returnBrokenResource(redis);
//			throw new RuntimeException(e);
//		}finally{
//			pool.returnResource(redis);
//		}
//	}
	
	public String getKey(final Long i) throws PiRedisExecption{
		
		return new RedisExecutor<String>() {
			@Override
			public String run() throws Exception {
				if(i>jedis.zcard(keyName)-1){
					return null;
				}
				 Set<String> keys = jedis.zrange(keyName, i, i);
				 for(String ip:keys){
					 return ip;
				 }
				 return null;
			}
		}.exec();
		
		
		
//		Jedis redis = null;
//		try{
//			
//			redis = getRedis();
//			if(i>redis.zcard(keyName)-1){
//				return null;
//			}
//			 Set<String> keys = redis.zrange(keyName, i, i);
//			 for(String ip:keys){
//				 return ip;
//			 }
//			 return null;
//		}catch(Exception e){
//			pool.returnBrokenResource(redis);
//			throw new RuntimeException(e);
//		}finally{
//			pool.returnResource(redis);
//		}
	}
	
	public List<String> getKeys(final Long start,final Long end) throws PiRedisExecption{
		return new RedisExecutor<List<String>>() {
			@Override
			public List<String> run() throws Exception {
				if(start>jedis.zcard(keyName)-1){
					return null;
				}
				 Set<String> keys = jedis.zrange(keyName, start, end);
				 return new ArrayList<String>(keys);
			}
		}.exec();
		
		
		
//		Jedis redis = null;
//		try{
//			
//			redis = getRedis();
//			if(start>redis.zcard(keyName)-1){
//				return null;
//			}
//			 Set<String> keys = redis.zrange(keyName, start, end);
//			 return new ArrayList<String>(keys);
//		}catch(Exception e){
//			pool.returnBrokenResource(redis);
//			throw new RuntimeException(e);
//		}finally{
//			pool.returnResource(redis);
//		}
	}

//	public Long update(String key, AbstractStoreBean value) throws Exception {
//		Jedis redis = null;
//		try{
//			redis = getRedis();
//			if(redis.zscore(keyName, key)==null){
//				redis.zadd(keyName, 0,key);
//				return redis.hset(storeName, key.getBytes(),SerializeUtil.serialize(value));
//			}else{
//				return null;
//			}
//		}finally{
//			pool.returnResource(redis);
//		}
//	}
	
	Random rand = new Random();
	public Long set(final String key) throws PiRedisExecption  {
		
		return new RedisExecutor<Long>() {
			@Override
			public Long run() throws Exception {
				if(jedis.zrank(keyName, key)==null){
					return jedis.zadd(keyName, rand.nextInt(1000),key);
				}else{
					return null;
				} 
			}
		}.exec();
		
		
//		Jedis redis = null;
//		try{
//			redis = getRedis();
//			if(redis.zrank(keyName, key)==null){
//				return redis.zadd(keyName, 0,key);
//			}else{
//				return null;
//			} 
//		}catch(Exception e){
//			pool.returnBrokenResource(redis);
//			throw new RuntimeException(e);
//		}finally{
//			pool.returnResource(redis);
//		}
	}
	

	@Override
	public Long remove(final String key) throws PiRedisExecption  {
		return new RedisExecutor<Long>() {
			@Override
			public Long run() throws Exception {
				return jedis.zrem(keyName, key);
			}
		}.exec();
		
		
		
//		Jedis redis = null;
//		try{
//			redis = getRedis();
////			redis.del(key.getBytes());
//			return redis.zrem(keyName, key);
//		}catch(Exception e){
//			pool.returnBrokenResource(redis);
//			throw new RuntimeException(e);
//		}finally{
//			pool.returnResource(redis);
//		}
	}

	public Long clear() throws PiRedisExecption  {
		return new RedisExecutor<Long>() {
			@Override
			public Long run() throws Exception {
				return jedis.del(keyName);
			}
		}.exec();
//		Jedis redis = null;
//		try{
//			redis = getRedis();
//			return redis.del(keyName);
//		}catch(Exception e){
//			pool.returnBrokenResource(redis);
//			throw new RuntimeException(e);
//		}finally{
//			pool.returnResource(redis);
//		}
	}

	
	@Override
	public List<ProxyIpBean> subList(final Long start,final Long end) throws PiRedisExecption {
//		final Long _start = start,_end = end;
		return new RedisExecutor<List<ProxyIpBean>>() {
			@Override
			public List<ProxyIpBean> run() throws Exception {
				List <ProxyIpBean> beans = new ArrayList<ProxyIpBean>();
				 
				 Set<String> keys = jedis.zrange(keyName, start, end-1);
				 
				 for(String key:keys){
					 ProxyIpBean bean = (ProxyIpBean) SerializeUtil.unserialize(jedis.get(key.getBytes()));
					
					 if(bean==null){
						 jedis.zrem(keyName, key);
						 continue;
					 }
					 
					 // @fb
					 //jedis.zrem(keyName, key);
					 beans.add(bean);
				 }
				 
				 return beans;
			}
		}.exec();
		
//		Jedis redis = null;
//		try{
//			redis = getRedis();
//			
//			List <ProxyIpBean> beans = new ArrayList<ProxyIpBean>();
//			 
//			 Set<String> keys = redis.zrange(keyName, start, end-1);
//			 for(String key:keys){
//				 
//				 ProxyIpBean bean = (ProxyIpBean) SerializeUtil.unserialize(redis.get(key.getBytes()));
//				 if(bean==null){
//					 redis.zrem(keyName, key);
//					 continue;
//				 }
//				 beans.add(bean);
//			 }
//			 return beans;
//		}catch(Exception e){
//			pool.returnBrokenResource(redis);
//			throw new RuntimeException(e);
//		}finally{
//			pool.returnResource(redis);
//		}
	}

	@Override
	public void clear(Transaction tran) {
		try{
			 tran.del(keyName);
		}finally{
		}
	}

//	@Override
//	public List<ProxyIpBean> subList(Transaction tran, Long start, Long end)
//			throws Exception {
//		try{
//			List <ProxyIpBean> beans = new ArrayList<ProxyIpBean>();
//			 Set<String> keys = tran.zrange(keyName, start, end-1).get();
//			 for(String key:keys){
//				 
//				 ProxyIpBean bean = (ProxyIpBean) SerializeUtil.unserialize(tran.get(key.getBytes()).get());
//				 if(bean==null){
//					 continue;
//				 }
//				 beans.add(bean);
//			 }
//			 return beans;
//		}finally{
//			
//		}
//	}

	@Override
	public void remove(Transaction tran, String key) throws Exception {
		try{
//			redis.del(key.getBytes());
			tran.zrem(keyName, key);
		}finally{
		}
	}

	@Override
	public void set(Transaction tran, String key) throws Exception {
			tran.zadd(keyName, 0,key);
	}
	
	@Override
	public void set(Transaction tran, int score, String key) throws Exception {
			tran.zadd(keyName, score,key);
	}

//	public static void main(String[] args) throws Exception {
//		Map map = new PoolMap("haha", new JedisPool("192.168.1.203",6379));
//		map.set("ddddd");
//		log.debug(map.containsKey("ddd"));
//	}


}
